package org.superheroes.androidserver;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.SocketException;

import org.superheroes.androidserver.io.VideoStream;
import org.superheroes.androidserver.net.RequestType;
import org.superheroes.androidserver.net.State;
import org.superheroes.androidserver.net.server.Server;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class ServerActivity extends Activity
{
	private static final String	LOG_TAG			= ServerActivity.class.getName();
	private static final String	LOG_ERROR_TAG	= ServerActivity.class.getName() + ".error";

	private final int			PORT			= 3030;
	private Server				server;

	private Button				startButton;
	private TextView			txtStatus;
	private String	status;	

	@Override
	protected void onCreate( Bundle savedInstanceState )
	{
		super.onCreate( savedInstanceState );
		setContentView( R.layout.activity_server );

		initControls();
		
		runOnUiThread( new Runnable()
		{
			
			@Override
			public void run()
			{
				if( status != null )
				{
					txtStatus.setText( status );
				}
			}
		} );
	}

	@Override
	public boolean onCreateOptionsMenu( Menu menu )
	{
		getMenuInflater().inflate( R.menu.server, menu );
		return true;
	}

	private void initControls()
	{
		status = "Initializing controls...";
		
		Log.i( LOG_TAG, status );
		
		txtStatus = ( TextView ) findViewById( R.id.textView1 );

		startButton = ( Button ) findViewById( R.id.startButton );
		startButton.setOnClickListener( new OnClickListener()
		{

			@Override
			public void onClick( View v )
			{
				status = "Start button clicked!";
				Log.i( LOG_TAG, status );
				
				try
				{

					Thread t = new Thread( new Runnable()
					{
						@Override
						public void run()
						{
							try
							{
								init();
							}
							catch ( Exception e )
							{
								Log.e( LOG_ERROR_TAG, e.toString() );
							}
						}
					} );

					t.start();

				}
				catch ( Exception e )
				{
					Log.e( LOG_ERROR_TAG, e.toString() );
				}
			}
		} );
		
		status = "Done initializing controls...";
	}
 
	private void init() throws Exception
	{
		status = "Initializing Server Activity";
		Log.i( LOG_TAG, status );

		server = Server.getServer();

		new Thread( clientConnector ).start();
	}
	
	Runnable clientConnector = new Runnable()
	{
		
		@Override
		public void run()
		{
			try
			{
				ServerSocket listenSocket = new ServerSocket( PORT );
			
				while( true )
				{
					server.setSocket( listenSocket.accept() );
					Thread clientStreamThread = new Thread( new Runnable()
					{
						
						@Override
						public void run()
						{
							server.setClientIPAddress( server.getSocket().getInetAddress() );
	
							server.setServerState( State.INIT );
							status = "INIT";
	
							try
							{
								server.setBufferedReader( new BufferedReader( new InputStreamReader( server.getSocket().getInputStream() ) ) );
								server.setBufferedWriter( new BufferedWriter( new OutputStreamWriter( server.getSocket().getOutputStream() ) ) );
							}
							catch( Exception e )
							{
								Log.e( LOG_ERROR_TAG, e.toString() );
							}
							
							RequestType requestType;
	
							boolean done = false;
	
							while ( ! done )
							{
								requestType = server.parseRequest();
	
								if ( requestType == RequestType.SETUP )
								{
									done = true;
	
									server.setServerState( State.READY );
									status = "READY";
									Log.i( LOG_TAG, "New RTSP State: READY" );
	
									server.sendResponse();
	
									//server.setVideo( new VideoStream( "res/raw/movie.mjpeg" ) );
									try
									{
										server.setVideo( new VideoStream("movie.Mjpeg") );
									}
									catch ( Exception e )
									{
										Log.e( LOG_ERROR_TAG, e.toString() );
									}
									status = "READY ("  + "res/raw/movie.mjpeg" + ")";
									
									try
									{
										server.setDatagramSocket( new DatagramSocket() );
									}
									catch ( SocketException e )
									{
										Log.e( LOG_ERROR_TAG, e.toString() );
									}
								}
							}
	
							while ( true )
							{
								requestType = server.parseRequest();
	
								if ( requestType == RequestType.PLAY && server.getServerState() == State.READY )
								{
									server.sendResponse();
									server.getTimer().start();
									server.setServerState( State.PLAYING );
									Log.i( LOG_TAG, "New RTSP State: PLAYING" );
									status = "PLAYING";
								}
								else if ( requestType == RequestType.PAUSE )
								{
									server.sendResponse();
									server.getTimer().stop();
									server.setServerState( State.READY );
									Log.i( LOG_TAG, "New RTSP State: READY" );
									status = "READY";
								}
								else if ( requestType == RequestType.TEARDOWN )
								{
									server.sendResponse();
									server.getTimer().stop();
									server.getDatagramSocket().close();
									try
									{
										server.getSocket().close();
									}
									catch ( IOException e )
									{
										Log.e( LOG_ERROR_TAG, e.toString() );
									}
									status = "TEARDOWN";
								}
							}
						}
					} );
					clientStreamThread.start();
				}
			}
			catch( Exception e )
			{
				Log.e( LOG_ERROR_TAG, e.toString() );
			}
		}
	};
}
